<?php
namespace app\index\controller\store;
use app\index\controller\BaseIndex;
use szktor\ClinicDict; //诊所门店公共字典
use app\common\model\ClinicDictsheet; //字典表数据
use app\common\model\ClinicAdmin; //诊所人员
use szktor\Random;

/*
* 前台-库房管理 -> 出库管理
* index/store.outstore/index
*/
class Outstore extends BaseIndex
{
    protected $noNeedLogin = [];  //无需登录的方法，同时也就不需要鉴权了
    protected $noNeedRight = []; //无需鉴权的方法，但需要登录

    //初始化
    public function initialize()
    {
        parent::initialize();
    }

    //首页
    public function index()
    {
        if($this->request->isPost() || $this->request->isAjax())
        {
            try
            {
                $post = $this->request->only(['create_time','xm_type','keyword','status','page'],'post');
                //条件
                $map = [
                    ['clinic_id','=', $this->admin['clinic_id']],
                    ['entry_type','=','1'], //出入类型0=入库,1=出库
                ];
                if(isset($post['xm_type']) && $post['xm_type'] != '')
                {
                    if(strtoupper($post['xm_type']) != 'ALL') $map[] = ['entry_sub_type','=',$post['xm_type']];
                }
                if(isset($post['status']) && $post['status'] != '')
                {
                    if(strtoupper($post['status']) != 'ALL') $map[] = ['status','=',(int)$post['status']];
                }
                if(isset($post['keyword']) && $post['keyword'] != '')
                {
                    $map[] = ['entry_sn|changjia|out_keshi|out_renyuan|add_name|confim_name|remarks','like','%' . $post['keyword'] . '%'];
                }
                //日期
                $rkDate = $this->getWhereDate($post['create_time']);
                if($rkDate) $map[] = ['create_time',['>=',$rkDate[0]],['<=',$rkDate[1]],'AND'];
                //分页
                $page = isset($post['page']) ? $post['page'] : 1;
                $limit = intval($this->pageNum) > 0 ? intval($this->pageNum) : 20;
                $list = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->where($map)->field('*')
                        ->order('id desc')->paginate($limit,false,['page' => $page, 'var_page' => 'page']);
                if (count($list) <= 0) {
                    return json(['code' => '1', 'msg' => '当前页下的数据已显示完毕！', 'count' => '0', 'data' => []]);
                }
                $res = ['code' => 0,'msg' => '', 'count' => $list->total(), 'data' => $list->items()];
                //仓库管理 - 出库类型
                $rk_type_list = ClinicDict::getChuKuTypeList();
                foreach ($res['data'] as $key => &$val) {
                    $val['entry_sub_type_txt'] = _getDictNameTxt($val['entry_sub_type'],$rk_type_list);
                    $val['create_time'] = $val['create_time'] > 0 ? date('Y-m-d',$val['create_time']) : '';
                }
                return json($res);
            }catch (\think\Exception $e){ // use think\Exception;
                return json(['err' => '500', 'msg' => '错误：' . $e->getMessage()]);
            }
        }
        $this->assign([
            'rk_type_list' => ClinicDict::getChuKuTypeList(), //仓库管理 - 出库类型
            //获取科室列表 Select 选择器使用
            'keshi_list' => ClinicDictsheet::getClinicKeShiList($this->admin['clinic_id'],true,'id,pid,name',['status' => '1']),
            //诊所人员
            'admin_list' => ClinicAdmin::getClinicAdminList($this->admin['clinic_id']),
        ]);
        return $this->view->fetch();
    }

    //修改 + 新增
    public function info($id = 0)
    {
        if($this->request->isAjax())
        {
            $data = $this->request->only([
                'id','create_time','out_keshi','entry_sub_type','out_renyuan','remarks','total_price','table_list',
            ],'post');
            if(!isset($data['id']))
            {
                return json(['err' => '1', 'msg' => '参数错误，无法执行']);
            }
            if(!isset($data['table_list']) || count($data['table_list']) <= 0)
            {
                return json(['err' => '2', 'msg' => '对不起，还未添加出库项目明细']);
            }
            $info = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')
                    ->where(['id' => intval($data['id']), 'entry_type' => '1', 'clinic_id' => $this->admin['clinic_id']])->find();
            $now_time = time();
            ClinicDictsheet::beginTransClinic($this->admin['clinic_id']);
            try
            {
                if($info) //数据已存在
                {
                    $sqlData = [
                        'entry_sub_type' => $data['entry_sub_type'], //出入子类型
                        'out_keshi' => $data['out_keshi'], //领用科室-出库字段
                        'out_renyuan' => $data['out_renyuan'], //领用人员-出库字段
                        'total_price' => $data['total_price'], //总金额
                        'add_name' => $this->getThisAdminName($this->admin), //制单人员
                        'confim_name' => '', //确认人员
                        'remarks' => $data['remarks'], //出出库备注
                        'status' => '0', //状态0未确认1已确认
                        'confim_time' => '0', //确认出出库时间
                        'create_time' => empty($data['create_time']) ? $now_time : strtotime($data['create_time']), //出出库时间
                    ];
                    $r1 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->where(['id' => $info['id']])->update($sqlData);
                    $r2 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->where(['entry_id' => $info['id']])->delete();
                    $entryId = $info['id'];
                }else{ //数据不存在
                    $entrySn = $this->buildUniqueEntrySn('O',4);
                    $sqlData = [
                        'clinic_id' => $this->admin['clinic_id'], //诊所ID
                        'entry_sn' => $entrySn, //出出库单号
                        'entry_type' => '1', //出入类型0=出库,1=出库
                        'entry_sub_type' => $data['entry_sub_type'], //出入子类型
                        'changjia' => '', //厂家供应商
                        'fapiao' => '', //发票号
                        'total_price' => $data['total_price'], //总金额
                        'out_keshi' => $data['out_keshi'], //领用科室-出库字段
                        'out_renyuan' => $data['out_renyuan'], //领用人员-出库字段
                        'add_name' => $this->getThisAdminName($this->admin), //制单人员
                        'confim_name' => '', //确认人员
                        'remarks' => $data['remarks'], //出出库备注
                        'status' => '0', //状态0未确认1已确认
                        'confim_time' => '0', //确认出出库时间
                        'create_time' => empty($data['create_time']) ? $now_time : strtotime($data['create_time']), //出出库时间
                    ];
                    $entryId = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->insertGetId($sqlData);
                    if(!$entryId)
                    {
                        ClinicDictsheet::commitTransClinic($this->admin['clinic_id']);
                        return json(['err' => '3', 'msg' => '对不起，添加出错，请重试']);
                    }
                }
                //明细数据
                $logData = [];
                foreach ($data['table_list'] as $key => $val) {
                    $jsonArr = $val['json'];
                    //出库的项目类型判断
                    $xmType = $this->getXmType($val['json']['ext_json']);
                    //出库数量过滤
                    $outNum = $val['num'] > $jsonArr['num'] ? $jsonArr['num'] : $val['num'];
                    if($outNum <= 0)
                    {
                        continue;
                    }
                    $logData[] = [
                        'clinic_id' => $this->admin['clinic_id'], //诊所ID
                        'entry_type' => '1', //出入类型0=入库,1=出库
                        'entry_id' => $entryId, //出库记录ID
                        'drugs_id' => $jsonArr['drugs_id'], //clinic_drugs表记录ID
                        'xm_type' => $xmType, //项目类型xy=西药,zcy=中成药,zyyp=中药饮片,zykl=中药颗粒,cl=材料
                        'batch_sn' => $val['batch_sn'], //出出库批号
                        'name' => $jsonArr['name'], //名称
                        'py_code' => $jsonArr['py_code'], //拼音码助记词
                        'wb_code' => $jsonArr['wb_code'], //五笔码助记词
                        'spec' => $jsonArr['spec'], //规格
                        'num' => $val['num'], //出出库数量
                        'unit' => $val['unit'], //单位
                        'price' => $val['price'], //进货单价
                        'total_price' => $val['price']*$val['num'], //进货总金额
                        'ls_price' => $val['ls_price'], //零售单价
                        'ls_total_price' => $val['ls_price']*$val['num'], //零售总金额
                        'changjia' => $val['changjia'], //厂家生产厂商
                        'chandi' => $val['chandi'], //产地
                        'except_time' => empty($val['except_time']) ? '0' : strtotime($val['except_time']), //有效期
                        'product_time' => empty($val['product_time']) ? '0' : strtotime($val['product_time']), //生产日期
                        'remarks' => '', //备注
                        'ext_json' => json_encode($jsonArr,JSON_UNESCAPED_UNICODE), //扩展json参数
                        'status' => '0', //状态0未确认1已确认
                        'create_time' => empty($data['create_time']) ? $now_time : strtotime($data['create_time']), //出出库时间
                    ];
                }
                if(count($logData) <= 0)
                {
                    ClinicDictsheet::rollbackTransClinic($this->admin['clinic_id']);
                    return ['err' => '2', 'msg' => '请检查出库数量是否输入正确'];
                }
                $editRes = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->insertAll($logData);
                ClinicDictsheet::commitTransClinic($this->admin['clinic_id']);
                unset($data,$info,$sqlData,$logData);
                return json(['err' => '0', 'msg' => '出库数据已保存成功']);
            }catch (\think\Exception $e){ // use think\Exception;
                ClinicDictsheet::rollbackTransClinic($this->admin['clinic_id']);
                return json(['err' => '500', 'msg' => '错误：' . $e->getMessage()]);
            }
        }else{
            //仓库管理 - 出库类型
            $rk_type_list = ClinicDict::getChuKuTypeList();
            //获取科室列表 Select 选择器使用
            $keshi_list = ClinicDictsheet::getClinicKeShiList($this->admin['clinic_id'],true,'id,pid,name',['status' => '1']);
            //诊所人员
            $admin_list = ClinicAdmin::getClinicAdminList($this->admin['clinic_id']);
            $info = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')
                    ->where(['id' => intval($id), 'entry_type' => '1', 'clinic_id' => $this->admin['clinic_id']])->find();
            $tableList = [];
            if($info){
                $info['entry_sub_type_txt'] = _getDictNameTxt($info['entry_sub_type'],$rk_type_list);
                $info['create_time'] = $info['create_time'] > 0 ? date('Y-m-d',$info['create_time']) : '';
                $tableList = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')
                           ->where(['entry_id' => $info['id']])->order('id asc')->select();
                foreach ($tableList as $key => &$val) {
                    $jsonArr = !$val['ext_json'] ? [] : json_decode($val['ext_json'],true);
                    $val['except_time'] = $val['except_time'] > 0 ? date('Y-m-d',$val['except_time']) : '';
                    $val['product_time'] = $val['product_time'] > 0 ? date('Y-m-d',$val['product_time']) : '';
                    if(count($jsonArr))
                    {
                        $jsonArr['num'] = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->where([
                            'id' => $jsonArr['id'],
                        ])->value('num');
                    }
                    $val['ext_json'] = $jsonArr;
                }
            }
            $this->assign([
                'info' => $info,
                'table_list' => $tableList, //子项目列表
                'rk_type_list' => $rk_type_list, //仓库管理 - 出库类型
                'keshi_list' => $keshi_list, //获取科室列表 Select 选择器使用
                'admin_list' => $admin_list, //诊所人员
            ]);
            return $this->view->fetch();
        }
    }
    //查看详情
    public function detail($id = 0)
    {
        //仓库管理 - 出库类型
        $rk_type_list = ClinicDict::getChuKuTypeList();
        //获取科室列表 Select 选择器使用
        $keshi_list = ClinicDictsheet::getClinicKeShiList($this->admin['clinic_id'],true,'id,pid,name',['status' => '1']);
        //诊所人员
        $admin_list = ClinicAdmin::getClinicAdminList($this->admin['clinic_id']);
        $info = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')
                ->where(['id' => intval($id), 'entry_type' => '1', 'clinic_id' => $this->admin['clinic_id']])->find();
        if(!$info)
        {
            return $this->redirect(Url::build('index/store.outstore/index'), '', 302);
        }
        $tableList = [];
        $info['entry_sub_type_txt'] = _getDictNameTxt($info['entry_sub_type'],$rk_type_list);
        $info['create_time'] = $info['create_time'] > 0 ? date('Y-m-d',$info['create_time']) : '';
        $tableList = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')
                   ->where(['entry_id' => $info['id']])->order('id asc')->select();
        foreach ($tableList as $key => &$val) {
            $val['ext_json'] = !$val['ext_json'] ? [] : json_decode($val['ext_json'],true);
            $val['except_time'] = $val['except_time'] > 0 ? date('Y-m-d',$val['except_time']) : '';
            $val['product_time'] = $val['product_time'] > 0 ? date('Y-m-d',$val['product_time']) : '';
        }
        $this->assign([
            'info' => $info,
            'table_list' => $tableList, //子项目列表
            'keshi_list' => $keshi_list, //获取科室列表 Select 选择器使用
            'admin_list' => $admin_list, //诊所人员
        ]);
        return $this->view->fetch();
    }
    //出库确认
    public function confim()
    {
        if(!$this->request->isAjax())
        {
            return json(['err' => '1', 'msg' => '对不起，您的访问方式有误']);
        }
        try
        {
            $data = $this->request->only(['id'],'post');
            if(!isset($data['id']) || intval($data['id']) <= 0)
            {
                return json(['err' => '1', 'msg' => '参数错误，无法执行']);
            }
            ClinicDictsheet::beginTransClinic($this->admin['clinic_id']);
            $map = [['id','in',$data['id']],['clinic_id','=',$this->admin['clinic_id']],['entry_type','=','1']];
            $res1 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->where($map)->update([
                'status' => '1', //状态0未确认1已确认
                'confim_name' => $this->getThisAdminName($this->admin), //确认人员
                'confim_time' => time(), //确认出出库时间
            ]);
            $entrySn = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->where($map)->value('entry_sn'); 
            $map1 = [['entry_id','in',$data['id']],['clinic_id','=',$this->admin['clinic_id']],['entry_type','=','1']];
            $list = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')
                    ->where($map1)->field('*')->order('id asc')->select();
            $inoutLogArr = [];
            foreach ($list as $key => $val) {
                $jsonArr = !$val['ext_json'] ? [] : json_decode($val['ext_json'],true);
                if(!count($jsonArr)) continue;
                $s1 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->where([
                    'id' => $jsonArr['id'], 'clinic_id' => $this->admin['clinic_id'],
                ])->setDec('num',$val['num']);
                $s2 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_drugs')->where([
                    'id' => $val['drugs_id'], 'clinic_id' => $this->admin['clinic_id'],
                ])->setDec('stock',$val['num']);
                //出入库库存变动明细
                $inoutLogArr[] = [
                    'clinic_id' => $val['clinic_id'], //诊所ID
                    'inout_sn' => $entrySn, //出入库单号
                    'type' => '1', //出入库方式0=入库,1=出库,2=盘点,3=发药,4=退药
                    'drugs_id' => $val['drugs_id'], //clinic_drugs表记录ID
                    'name' => $val['name'], //名称
                    'py_code' => $val['py_code'], //拼音码助记词
                    'wb_code' => $val['wb_code'], //五笔码助记词
                    'batch_sn' => $val['batch_sn'], //出入库批号
                    'num' => '-' . $val['num'], //出入库数量
                    'unit' => $val['unit'], //单位
                    'price' => $val['price'], //进货单价
                    'ls_price' => $val['ls_price'], //零售单价
                    'except_time' => $val['except_time'], //有效期
                    'changjia' => $val['changjia'], //厂家生产厂商
                    'remarks' => $val['remarks'], //备注
                    'create_time' => $val['create_time'], //出入库时间
                ];
            }
            $res2 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->where($map1)->update([
                'status' => '1', //状态0未确认1已确认
            ]);
            $res3 = ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_inout_log')->insertAll($inoutLogArr);
            unset($inoutLogArr);
            ClinicDictsheet::commitTransClinic($this->admin['clinic_id']);
            return json(['err' => '0', 'msg' => '出库确认成功']);
        }catch (\think\Exception $e){ // use think\Exception;
            ClinicDictsheet::rollbackTransClinic($this->admin['clinic_id']);
            return json(['err' => '500', 'msg' => '错误：' . $e->getMessage()]);
        }
    }
    //出库删除
    public function del()
    {
        if(!$this->request->isAjax())
        {
            return json(['err' => '1', 'msg' => '对不起，您的访问方式有误']);
        }
        try
        {
            $data = $this->request->only(['id'],'post');
            if(!isset($data['id']) || intval($data['id']) <= 0)
            {
                return json(['err' => '1', 'msg' => '参数错误，无法执行']);
            }
            ClinicDictsheet::beginTransClinic($this->admin['clinic_id']);
            $map = [['id','in',$data['id']],['clinic_id','=',$this->admin['clinic_id']],['entry_type','=','1']];
            $res1 = false !== ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry')->where($map)->delete();
            $map1 = [['entry_id','in',$data['id']],['clinic_id','=',$this->admin['clinic_id']],['entry_type','=','1']];
            $res2 = false !== ClinicDictsheet::getSplitDb($this->admin['clinic_id'],'clinic_entry_log')->where($map1)->delete();
            $res = $res1 && $res2;
            ClinicDictsheet::checkTransClinic($res,$this->admin['clinic_id']);
            if(!$res) return json(['err' => '2', 'msg' => '出库数据删除失败，请重试']);
            return json(['err' => '0', 'msg' => '出库数据删除成功']);
        }catch (\think\Exception $e){ // use think\Exception;
           return json(['err' => '500', 'msg' => '错误：' . $e->getMessage()]);
        }
    }
    /**
    *生成唯一字段值 唯一   出入为单号
    */
    private function buildUniqueEntrySn($pre = 'O', $len = 4, $fields = 'entry_sn')
    {
        $isExists = true;
        $tmpCode = '';
        do {
            $tmpCode = $pre . date('YmdH') . strtoupper(Random::numeric($len)); //数字
            $isExists = $this->checkUniqueCode($tmpCode,$fields,'clinic_entry');
        } while ($isExists);
        return $tmpCode;
    }
}
